﻿using System;
using System.Collections.Generic;
using System.Linq;
using yiCommerce.Core;
using yiCommerce.Core.Data;
using yiCommerce.Core.Domain.Addresses;
using yiCommerce.Core.Domain.Customers;
using yiCommerce.Core.Domain.Products;
using yiCommerce.Core.Domain.Securitys;
using yiCommerce.Core.Domain.ShoppingCarts;
using yiCommerce.Core.Domain.Shops;

namespace yiCommerce.Service.Customers
{
    public class CustomerService:ICustomerService
    {
        private IRepository<Address> _addressRepository;
        private IRepository<Customer> _customerRepository;
        private IRepository<CustomerRole> _customerRoleRepository;
        private IRepository<CustomerLogo> _customerLogoRepository;


        public CustomerService(IRepository<Address> addressRepository, IRepository<Customer> customerRepository, IRepository<CustomerRole> customerRoleRepository, IRepository<CustomerLogo> customerLogoRepository)
        {
            _addressRepository = addressRepository;
            _customerRepository = customerRepository;
            _customerRoleRepository = customerRoleRepository;
            _customerLogoRepository = customerLogoRepository;
        }

        public IPagedList<Customer> GetAllCustomers(int pageIndex, int pageSize)
        {

            var query = _customerRepository.Table;

             var tempResult = new PagedList<Customer>(query, pageIndex, pageSize);

            return tempResult;
        }

        public IList<Customer> GetCustomersByCustomerRoleId(int customerRoleId)
        {
            throw new System.NotImplementedException();
        }

        public void DeleteCustomer(Customer customer)
        {
            throw new System.NotImplementedException();
        }

        public Customer GetCustomerById(int customerId)
        {
            var query = from c in _customerRepository.Table
                        where c.Id == customerId
                        select c;
            var customer = query.FirstOrDefault();
            if (customer != null)
            {

                return CustomerMapper.ToCustomer(customer);
            }
            else
            {
                return null;
            }
        }

        public Customer InsertGuestCustomer()
        {
            var customer = new Customer()
            {
                UserGuid = Guid.NewGuid(),
                Active = true,
                CreatedOn= DateTime.Now,
            };

            //add to 'Guests' role
            var guestRole = GetCustomerRoleBySystemName(SystemCustomerRoleNames.Guests);
            if (guestRole == null)
                throw new Exception("'Guests' role could not be loaded");
            customer.CustomerRoles.Add(guestRole);

            _customerRepository.Insert(customer);

            return customer;
        }

        public Customer GetCustomerByUserName(string userName)
        {
            if (string.IsNullOrWhiteSpace(userName))
                return null;

            var query = from c in _customerRepository.Table
                        orderby c.Id
                        where c.Username==userName 
                        select c;
            var customer = query.FirstOrDefault();
            if (customer != null)
            {

                return CustomerMapper.ToCustomer(customer);
            }
            else
            {
                return null;
            }
        }

        CustomerRole ICustomerService.GetCustomerRoleBySystemName(string roleName)
        {
            return GetCustomerRoleBySystemName(roleName);
        }

        public IList<CustomerRole> GetAllCustomerRoles()
        {
            return _customerRoleRepository.Table.ToList();
        }

        private CustomerRole GetCustomerRoleBySystemName(string rolename)
        {
            var query = from cr in _customerRoleRepository.Table
                        orderby cr.Id
                        where cr.SystemName == rolename
                        select cr;
            var customerRole = query.FirstOrDefault();
            return customerRole;
        }

        public IList<Customer> GetAllNotUsedShopOwners()
        {
            throw new System.NotImplementedException();
        }

        public void UpdateCustomerLogo(int customerId, int logoId, int pictureId)
        {
            var cust = _customerRepository.GetById(customerId);

            var customerLog = _customerLogoRepository.GetById(cust.CustomerLogoId);
            customerLog.PictureId = pictureId;

            _customerLogoRepository.Update(customerLog);
        }

        public void InsertCustomerLogo(int customerId, int pictureId)
        {
            var customerLog = new CustomerLogo()
                {
                    PictureId = pictureId, 
                    DisplayOrder = 0,
                };
            _customerLogoRepository.Insert(customerLog);
            var cust = _customerRepository.GetById(customerId);

            cust.CustomerLogoId = customerLog.Id;

            _customerRepository.Update(cust);

        }

        public void UpdateCustomerInfo(int customerId, string nickName, string intro)
        {
            var cust = _customerRepository.GetById(customerId);

            cust.NickName = nickName;
            cust.Intro = intro;

            _customerRepository.Update(cust);
        }
        public void UpdateCustomer(Customer customer)
        {
            if (customer == null)
                throw new ArgumentNullException("customer");

            var cust = _customerRepository.GetById(customer.Id);
            cust.Addresses.Clear();
            foreach (var ad in customer.Addresses)
            {
                cust.Addresses.Add(_addressRepository.GetById(ad.Id));
            }

            cust.CustomerRoles.Clear();
            foreach (var cr in customer.CustomerRoles)
            {
                cust.CustomerRoles.Add(_customerRoleRepository.GetById(cr.Id));
            }

            if (customer.ShippingAddress != null)
            {
                cust.ShippingAddress = _addressRepository.GetById(customer.ShippingAddress.Id);
            }

            cust.SelectedPaymentMethodSystemName = customer.SelectedPaymentMethodSystemName;
            cust.Username = customer.Username;
            cust.Email = customer.Email;
            cust.Password = customer.Password;
            cust.Active = customer.Active;
            
            _customerRepository.Update(customer);
        }

        public Customer GetCustomerByEmail(string usernameOrEmail)
        {
            if (string.IsNullOrWhiteSpace(usernameOrEmail))
                return null;

            var query = from c in _customerRepository.Table
                        where c.Email == usernameOrEmail
                        select c;
            var customers = query.ToList();
            if (customers != null)
            {

                var customer = customers[0];
                return CustomerMapper.ToCustomer(customer);
            }
            else
            {
                return null;
            }

            //if (string.IsNullOrWhiteSpace(usernameOrEmail))
            //    return null;

            //var query = from c in _customerRepository.Table
            //            where c.Email == usernameOrEmail
            //            select c;
            //var customer = query.SingleOrDefault();
            //if (customer != null)
            //{

            //    return CustomerMapper.ToCustomer(customer);
            //}
            //else
            //{
            //    return null;
            //}
        }

       

       
       

       

        public Customer GetUserByGuid(Guid customerGuid)
        {
            var query = from c in _customerRepository.Table
                        where c.UserGuid ==customerGuid 
                        select c;
            var customer = query.FirstOrDefault();
            if (customer != null)
            {

                return CustomerMapper.ToCustomer(customer);
            }
            else
            {
                return null;
            }
        }
    }
}